<?php

require_once ROOT_SERVICES_MODEL . DS . 'models_warehouse.php';
require_once ROOT_SERVICES_MODEL . DS . 'models_oms_mapper.php';
require_once ROOT_SERVICES_MODEL . DS . 'models_rule.php';
require_once ROOT_SERVICES_HELPER . DS . 'check_date.php';
require_once ROOT_LIBRARY_LAZADA . DS . 'global_vars.php';
require_once ROOT_LIBRARY_LAZADA . DS . 'benchmark.php';

class oms_shipping {

    const DELIVERED_STATUS = "27";

    private $_db;
    private $_cache;
    private $_rules;
    private $_all_shipment_type = array();
    private $_all_payment_method = array();
    private $_holidays = array();
    private $_wh;

    public function __construct($db, $cache) {

        $this->_db = $db;
        $this->_cache = $cache;
        $this->_wh = new models_warehouse($this->_db, $this->_cache);
        $models_rules = new models_rule($this->_db, $this->_cache);

        $this->_all_payment_method = $this->_wh->get_all_payment_method();
        $this->_all_shipment_type = $this->_wh->get_all_shippment_type();
        $this->_rules = $models_rules->get_rules();
        $this->_holidays = array();
    }

    public function get_status_shipping($order_number) {
	
        $order = $this->_wh->get_order_id($order_number);
        $info_order = $this->_wh->get_info_item_order($order['id_sales_order']);
		
        $status_order = array();
        foreach ($info_order as $item_row) {
            $shipment = $this->_wh->get_shipment_provider_by_package($item_row['id_package']);
            $info_status_list = $this->get_list_status_item($item_row['id_sales_order_item'], $order, $shipment);

            $status_order[$item_row['sku']]['name'] = $item_row['name'];
            $status_order[$item_row['sku']]['is_shipped'] = isset($item_row['id_package']) && isset($item_row['fk_shipment_provider']);
            $status_order[$item_row['sku']]['list_package'][] = array(
                'id_package' => $item_row['id_package'],
                'amount' => $item_row['amount'],
                'id_sales_order_item' => $item_row['id_sales_order_item'],
                'fk_shipment_provider' => $item_row['fk_shipment_provider'],
                'tracking_number' => $item_row['tracking_number'],
                'shipment_provider_name' => $item_row['shipment_provider_name'],
                'fk_sales_order_item_status' => $item_row['fk_sales_order_item_status'],
                'last_status_in_wh' => $info_status_list['last_status_in_wh'],
                'id_package' => $item_row['id_package'],
                'created_at' => $item_row['created_at'],
                'list_status' => $info_status_list['status_list']
            );
        }
        usort($status_order, array('oms_shipping', 'cmp_last_status'));
        $order['list_status_order'] = $this->_wh->get_status_history_order($order['id_sales_order']);
        return array('order' => $order, 'status_items' => $status_order);
    }

    private function get_list_status_item($id_item, $order, $shipment) {
		
        $wh_status = $this->get_order_warehouse_status_by_item($id_item, $order, $shipment);
        //$shipment_status =  array(); //$this->get_shipment_provider_status($shipment);

        $status_list = $wh_status['status_list'];
        //if (!empty($shipment_status['status_list'])) {
        //    foreach ($shipment_status['status_list'] as $ps) {
        //        $status_list[] = array('id' => '', 'time' => $ps['time'], 'status' => $ps['status']);
        //    }
        //}
        //$status_list = array_merge($status_list, $wh_status['status_list']);

        //if ($shipment_status['sortable']) {
        //    if (!empty($status_list)) {
        //        usort($status_list, array('oms_shipping', 'cmp_time'));
        //    }
        //}
        return array('status_list' => $status_list, 'last_status_in_wh' => $wh_status['last_status_in_wh']);
    }

    public function get_order_warehouse_status_by_item($id_sales_order_item, $order, $shipment) {
        $wh_status_order = $this->_wh->get_status_history_by_order_item($id_sales_order_item);
        $rules_display = array();

        //check rules for each status.
        foreach ($wh_status_order as $status_order) {
            foreach ($this->_rules as $rule) {
                if ($this->_check_rule($status_order, $rule, $order, $shipment)) {
                    $rules_display[] = array('id' => $status_order['id'], 'time' => $status_order['time'], 'status' => $rule['display_status']);
                }
            }
        }
        return array('sortable' => TRUE, 'status_list' => $rules_display, 'last_status_in_wh' => $rules_display[0]['id']);
    }

    
    
    
    
    
    
    
    
    /** Utility funcions * */
    private function _check_rule($status, $rule, $order, $shipment) {		
        $payment_method_rules = json_decode($rule['payment_type_json'], true);
        if (empty($payment_method_rules)) // all payment method
            $payment_method_rules = $this->_all_payment_method;

        $shipment_type_rules = json_decode($rule['shipment_provider_json'], true);
        if (empty($shipment_type_rules)) // all shiment type
            $shipment_type_rules = $this->_all_shipment_type;

        $time_rules = json_decode($rule['time_in_status_json'], true);
        check_date::set_option($time_rules);
        check_date::set_holidays($this->_holidays);

        $result = ($status['id'] == $rule['fk_sales_order_item_status']) &&
                in_array($order['payment_method'], $payment_method_rules) &&
                (in_array($shipment['id_shipment_provider'], $shipment_type_rules) || !isset($shipment['id_shipment_provider'])) &&
                check_date::check_time_status($status['time'], $time_rules['time_in_status']);
        return $result;
    }

    private function get_shipment_provider_status($shipment) {
	
        $result = array('sortable' => FALSE, 'status_list' => null);
        if ($shipment) {
            $country = global_vars::instance()->get('local_db');
			
			$classname = "shipping_provider_simple_{$shipment['id_shipment_provider']}";
            $shipping_provider_file = ROOT_SERVICES . DS . "shipping_provider" . DS . $country . DS . $classname . ".php";

            if (file_exists($shipping_provider_file)) {
			
                include_once $shipping_provider_file;
                $class = new $classname($shipment);
                if ($class instanceof shipping_provider_interface) {
                    $result = $class->get_status_shipping();
                }
				
            }
        }
        return array('sortable' => $result['sortable'], 'status_list' => $result['status_list']);
    }

    private static function cmp_time($a, $b) {
        return strtotime($b['time']) - strtotime($a['time']) >= 0;
    }

    private static function cmp_last_status($a, $b) {
        return $b['list_package'][0]['last_status_in_wh'] - $a['list_package'][0]['last_status_in_wh'];
    }

}

?>
